<template>
  <div class="vxe_table_container">
    <div style="height: 100%">
      <component
        :is="tableName"
        v-bind="getProps"
        ref="xGrid"
        :columns="columns"
        :loading="loading"
        :empty-text="emptyText"
        :data="itableData"
        class="xtable-scrollbar"
        @checkbox-change="$emit('selection-change', getCheckboxRecords())"
        @radio-change="$emit('radio-change', getRadioRecord())"
        @custom="toolbarCustomEvent"
      >
        <template v-for="item in Object.keys($slots)" #[item]="data" :key="item">
          <slot :name="item" v-bind="data || {}"></slot>
        </template>
        <template v-for="(item, index) in columns" :key="index">
          <vxe-column v-if="!item.hide" :column-key="item.field" v-bind="item">
            <template #default="scope">
              <slot :name="item.field" v-bind="scope">
                <template v-if="item.bordered === 0">
                  <el-input v-model="scope.row[item.field]" :input-style="{ textAlign: item.alignItem }" clearable />
                </template>
                <template v-if="item.bordered === 1">
                  <el-input v-model="scope.row.subjectIdAndName" placeholder="" clearable>
                    <template #append>
                      <el-button :icon="item.icon.indexOf('el') !== -1 ? item.icon : null">
                        {{ item.icon.indexOf('el') === -1 ? item.icon : null }}
                      </el-button>
                    </template>
                  </el-input>
                </template>
                <template v-if="item.bordered === 2">
                  {{ scope.row[item.field] }}
                </template>
              </slot>
            </template>
          </vxe-column>
        </template>
      </component>
    </div>
  </div>
  <div v-if="!hidePaginationAll" class="axTable-page">
    <div class="scTable-pagination">
      <el-pagination
        v-if="!hidePagination"
        v-model:current-page="pagerConfig.currentPage"
        background
        :small="true"
        :layout="paginationLayout"
        :total="pagerConfig.total"
        :page-size="pagerConfig.pageSize"
        :page-sizes="pagerConfig.pageSizes"
        :pager-count="4"
        @current-change="pageChange"
        @update:page-size="sizeChange"
      ></el-pagination>
    </div>
    <div class="scTable-do">
      <vxe-toolbar ref="toolbarRef" custom :refresh="{ query: reload }"></vxe-toolbar>
    </div>
  </div>
</template>

<script>
import { ElMessage } from 'element-plus';

import $API from '@/api';
import config from '@/config/table';
import message from '@/utils/message';

let proxyForm;

const pagerConfig = {
  border: false, // 带边框
  background: false, // 带背景颜色
  perfect: false, // 配套的样式
  pageSize: 100, // 每页大小
  // pagerCount: 7, // 显示页码按钮的数量
  autoHidden: false, // 当只有一页时自动隐藏
  pageSizes: [100, 500, 1000, 10000, 100000], // 每页大小选项列表
  currentPage: 1,
  total: 0,
  layouts: ['PrevJump', 'PrevPage', 'JumpNumber', 'NextPage', 'NextJump', 'Sizes', 'FullJump', 'Total'],
};
export default {
  props: {
    data: {
      type: Array,
      default: () => [],
    },
    hidePagination: {
      type: Boolean,
      default: false,
    },
    hidePaginationAll: {
      type: Boolean,
      default: false,
    },
    columns: { type: Array, default: () => [] },
    paginationLayout: { type: String, default: config.paginationLayout },
    pageSize: {
      type: Number,
      default: 100,
    },
  },
  data() {
    return {
      prefixCls: '',
      pagerConfig: { ...pagerConfig },
      loading: false,
      summary: {},
      emptyText: '暂无数据',
      prop: null,
      order: null,
      itableData: [],
      tableRef: null,
    };
  },
  computed: {
    props() {
      return this.$attrs;
    },
    tableName() {
      return this.columns.length ? 'VxeGrid' : 'VxeTable';
    },
    getProps() {
      const options = { ...this.$attrs };
      options.height = 'auto';
      options['header-row-class-name'] = 'custom_header';
      this.getOptionInitConfig(options);
      this.getColumnsConfig(options);
      this.getProxyConfig(options);
      // this.getPageConfig(options)
      this.getToolBarConfig(options);
      return {
        ...options,
      };
    },
  },
  watch: {
    data: {
      handler(newVal) {
        this.itableData = newVal;
      },
      immediate: true,
    },
    pageSize: {
      handler() {
        this.pagerConfig.pageSize = this.pageSize;
      },
      immediate: true,
    },
  },
  mounted() {
    this.$nextTick(() => {
      const $table = this.$refs.xGrid;
      this.tableRef = this.$refs.xGrid;
      console.log(this.tableName, this.getProps, $table.getColumns());
      if (!this.hidePaginationAll) {
        const $toolbar = this.$refs.toolbarRef;
        if ($table && $toolbar) {
          $table.connect($toolbar);
        }
      }
    });
  },
  methods: {
    toolbarCustomEvent() {
      const $table = this.$refs.xGrid;
      if ($table) {
        const visibleColumn = $table.getColumns();
        console.log(visibleColumn);
      }
    },
    /** 初始化参数 */
    getOptionInitConfig(options) {
      options.rowConfig = {
        isCurrent: true, // 当鼠标点击行时，是否要高亮当前行
        isHover: true, // 当鼠标移到行时，是否要高亮当前行
      };
      options.seqConfig = {
        seqMethod: (scope) => {
          return (this.pagerConfig.currentPage - 1) * this.pagerConfig.pageSize + scope.rowIndex + 1;
        },
      };
      options.customConfig = {
        mode: 'popup',
        storage: {
          visible: true,
          resizable: true,
          sort: true,
          fixed: true,
        },
        restoreStore({ id }) {
          console.log('restoreStore', id);
          // eslint-disable-next-line no-async-promise-executor
          return new Promise(async (resolve) => {
            try {
              if (id) {
                await $API.sysEntityColumn.list.get({
                  id,
                });
                /* console.log('=====restoreStore======',res);
               
                ElMessage({
                  type: 'success',
                  message: '异步还原用户个性化数据成功'
                }) */
                resolve(JSON.parse(sessionStorage.getItem(id) || ''));
              } else {
                resolve({});
              }
            } catch (e) {
              resolve({});
            }
          });
        },
        updateStore({ id, storeData }) {
          console.log('updateStore_id', id);
          console.log('params', {
            id,
            columnSettings: JSON.stringify(storeData),
          });
          // eslint-disable-next-line no-async-promise-executor
          return new Promise(async (resolve) => {
            await $API.sysEntityColumn.create.post({
              id,
              columnSettings: JSON.stringify(storeData),
            });
            console.log('storeData', storeData);
            sessionStorage.setItem(id, JSON.stringify(storeData));
            ElMessage({
              type: 'success',
              message: '保存用户个性化数据成功',
            });
            resolve();
          });
        },
      };
    },
    /** columns参数 */
    getColumnsConfig(options) {
      const { allSchemas } = options;
      if (!allSchemas) return;
      if (allSchemas.printSchema) {
        options.printConfig = {
          columns: allSchemas.printSchema,
        };
      }
      if (allSchemas.formSchema) {
        proxyForm = true;
        options.formConfig = {
          enabled: true,
          titleWidth: 100,
          titleAlign: 'right',
          items: allSchemas.searchSchema,
        };
      }
      if (allSchemas.tableSchema) {
        options.columns = allSchemas.tableSchema;
      }
    },
    /**
     * @description 动态请求
     */

    getProxyConfig(options) {
      const { apiObj } = options;
      if (apiObj) {
        this.apiObj = apiObj;
        return this.getData();
      }
      const { getListApi, proxyConfig, data, isList } = options;
      if (proxyConfig || data) return;
      if (getListApi && typeof getListApi === 'function') {
        if (!isList) {
          options.proxyConfig = {
            seq: true, // 启用动态序号代理（分页之后索引自动计算为当前页的起始序号）
            form: proxyForm, // 启用表单代理，当点击表单提交按钮时会自动触发 reload 行为
            props: { result: 'list', total: 'total' },
            ajax: {
              query: async ({ page, form }) => {
                let queryParams = { ...JSON.parse(JSON.stringify(form)) };
                if (options.params) {
                  queryParams = Object.assign(queryParams, options.params);
                }
                if (!options?.treeConfig) {
                  queryParams.pageSize = page.pageSize;
                  queryParams.pageNo = page.currentPage;
                }
                try {
                  const res = await getListApi(queryParams);
                  const response = res;
                  if (response.code != config.successCode) {
                    this.loading = false;
                    this.emptyText = response.msg;
                  } else {
                    this.emptyText = '暂无数据';
                    if (this.hidePagination) {
                      this.tableData = response.data || [];
                    } else {
                      this.tableData = response.rows || [];
                    }
                    this.total = response.total || 0;
                    this.summary = response.summary || {};
                    this.loading = false;
                  }
                  // this.$refs.scTable.setScrollTop(0)
                  this.$emit('dataChange', res, this.tableData);
                } catch (error) {
                  console.log(error);
                }
              },
              delete: ({ body }) => {
                return new Promise((resolve) => {
                  if (options.deleteApi) {
                    resolve(options.deleteApi(JSON.stringify(body)));
                  } else {
                    Promise.reject('未设置deleteApi');
                  }
                });
              },
              queryAll: ({ form }) => {
                const queryParams = { ...JSON.parse(JSON.stringify(form)) };
                return new Promise((resolve) => {
                  if (options.getAllListApi) {
                    resolve(options.getAllListApi(queryParams));
                  } else {
                    resolve(getListApi(queryParams));
                  }
                });
              },
            },
          };
        } else {
          options.proxyConfig = {
            seq: true, // 启用动态序号代理（分页之后索引自动计算为当前页的起始序号）
            form: true, // 启用表单代理，当点击表单提交按钮时会自动触发 reload 行为
            props: { result: 'data' },
            ajax: {
              query: ({ form }) => {
                let queryParams = { ...JSON.parse(JSON.stringify(form)) };
                if (options?.params) {
                  queryParams = Object.assign(queryParams, options.params);
                }
                return new Promise((resolve) => {
                  resolve(getListApi(queryParams));
                });
              },
            },
          };
        }
      }
      if (options.exportListApi) {
        options.exportConfig = {
          filename: options?.exportName,
          // 默认选中类型
          type: 'csv',
          // 自定义数据量列表
          modes: options?.getAllListApi ? ['current', 'all'] : ['current'],
          columns: options?.allSchemas?.printSchema,
        };
      }
    },
    /** 分页参数 */
    getPageConfig(options) {
      const { pagination, pagerConfig, treeConfig, isList } = options;
      if (isList) return;
      if (treeConfig) {
        // options.treeConfig = options.treeConfig
        return;
      }
      if (pagerConfig) return;
      if (pagination) {
        if (typeof pagination === 'boolean') {
          this.pagerConfig = { ...pagerConfig };
          return;
        }
        this.pagerConfig = { ...pagerConfig, ...pagination };
      } else if (pagination != false) {
        this.pagerConfig = { ...pagerConfig };
      }
    },
    /** Toobar参数 */
    getToolBarConfig(options) {
      const { toolBar, toolbarConfig, topActionSlots } = options;
      if (toolbarConfig) return;
      if (toolBar) {
        if (typeof toolBar !== 'boolean') {
          options.toolbarConfig = toolBar;
        }
      } else if (topActionSlots != false) {
        options.toolbarConfig = {
          slots: { buttons: 'toolbar_buttons' },
        };
      } else {
        options.toolbarConfig = {
          enabled: true,
        };
      }
    },
    // 获取数据
    async getData() {
      // const {} = this.props
      this.loading = true;
      const reqData = {
        [config.request.page]: this.pagerConfig.currentPage,
        [config.request.pageSize]: this.pagerConfig.pageSize,
        [config.request.prop]: this.prop,
        [config.request.order]: this.order,
      };
      if (this.hidePagination) {
        delete reqData[config.request.page];
        delete reqData[config.request.pageSize];
      }
      Object.assign(reqData, this.tableParams);

      try {
        var res = await this.apiObj.get(reqData);
      } catch (error) {
        this.loading = false;
        this.emptyText = error.statusText;
        return false;
      }
      try {
        var response = config.parseData(res);
      } catch (error) {
        this.loading = false;
        this.emptyText = '数据格式错误';
        return false;
      }
      if (response.code != config.successCode) {
        this.loading = false;
        this.emptyText = response.msg;
      } else {
        this.emptyText = '暂无数据';
        if (this.hidePagination) {
          this.itableData = response.data || [];
        } else {
          this.itableData = response.rows || [];
        }
        this.pagerConfig.total = response.total || 0;
        this.summary = response.summary || {};
        this.loading = false;
      }
      // this.$refs.scTable.setScrollTop(0)
      this.$emit('dataChange', res, this.itableData);
    },
    pageChange() {
      this.getData();
    },
    sizeChange(size) {
      this.pagerConfig.currentPage = 1;
      this.pagerConfig.pageSize = size;
      this.getData();
    },
    // reload() {
    //   const g = this.$refs.xGrid
    //   if (!g) {
    //     return
    //   }
    //   g.commitProxy('query')
    // },
    reload(params, page = 1) {
      this.currentPage = page;
      this.tableParams = params || {};
      this.$refs.xGrid.clearRadioRow();
      this.$refs.xGrid.clearCheckboxRow();
      this.$refs.xGrid.clearSort();
      this.$refs.xGrid.clearFilter();
      this.getData();
    },
    async deleteData(id) {
      const g = this.$refs.xGrid;
      if (!g) {
        return;
      }
      const options = this.props;
      if (!options.deleteApi) {
        console.error('未传入delListApi');
        return;
      }
      return new Promise(() => {
        message.delConfirm().then(async () => {
          await (options?.deleteApi && options?.deleteApi(id));
          message.success('删除成功');
          // 刷新列表
          this.reload();
        });
      });
    },
    async deleteBatch() {
      const g = this.$refs.xGrid;
      if (!g) {
        return;
      }
      const rows = g.getCheckboxRecords() || g.getRadioRecord();
      const ids = [];
      if (rows.length == 0) {
        message.error('请选择数据');
        return;
      }
      rows.forEach((row) => {
        ids.push(row.id);
      });

      const options = this.props;
      if (options.deleteListApi) {
        return new Promise(() => {
          message.delConfirm().then(async () => {
            await (options?.deleteListApi && options?.deleteListApi(ids));
            message.success('删除成功');
            // 刷新列表
            this.reload();
          });
        });
      }
      if (options.deleteApi) {
        return new Promise(() => {
          message.delConfirm().then(async () => {
            ids.forEach(async (id) => {
              await (options?.deleteApi && options?.deleteApi(id));
            });
            message.success('删除成功');
            // 刷新列表
            this.reload();
          });
        });
      }
      console.error('未传入delListApi');
    },
    getSearchData() {
      const g = this.$refs.xGrid;
      if (!g) {
        return;
      }
      const queryParams = { ...JSON.parse(JSON.stringify(g.getProxyInfo()?.form)) };
      return queryParams;
    },
    getCurrentColumn() {
      const g = this.$refs.xGrid;
      if (!g) {
        return;
      }
      return g.getCurrentColumn();
    },
    getRadioRecord() {
      const g = this.$refs.xGrid;
      if (!g) {
        return;
      }
      return g.getRadioRecord(false);
    },
    getCheckboxRecords() {
      const g = this.$refs.xGrid;
      if (!g) {
        return;
      }
      return g.getCheckboxRecords(false);
    },
    print() {
      const g = this.$refs.xGrid;
      if (!g) {
        return;
      }
      return g.print(...arguments);
    },
    openPrint() {
      const g = this.$refs.xGrid;
      if (!g) {
        return;
      }
      return g.openPrint(...arguments);
    },
    openExport() {
      const g = this.$refs.xGrid;
      if (!g) {
        return;
      }
      return g.openExport(...arguments);
    },
    importData() {
      const g = this.$refs.xGrid;
      if (!g) {
        return;
      }
      return g.importData(...arguments);
    },
    upData(params, page = 1) {
      this.pagerConfig.currentPage = page;
      this.$refs.xGrid.clearCheckboxRow();
      this.$refs.xGrid.clearRadioRow();
      this.tableParams = this.tableParams || {};
      Object.assign(this.tableParams, params || {});
      this.getData();
    },
    setProps() {},
    reloadColumn(columns) {
      this.$refs.xGrid.reloadColumn(columns);
    },
  },
};
</script>

<style lang="scss">
#app {
  --vxe-font-size: 12px;
  --vxe-table-header-font-weight: 700;
  --vxe-table-header-font-color: var(--el-text-color-secondary);
  --vxe-font-family: Microsoft YaHei;
}

.vxe_table_container {
  height: calc(100% - 51px);
}

.ax-table-page.vxe-pager {
  .vxe-pager--right-wrapper {
    float: right;

    .vxe-toolbar {
      padding: 0;
    }
  }
}

.custom_header {
  th {
    padding: 9px 0 !important;
  }
}
</style>
<style scoped>
.axTable-page {
  height: 50px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 15px;
}
</style>
